package util.rm.quml.gemom;

import java.util.*;
import java.text.NumberFormat;

import patch.apache.commons.math.stat.correlation.Covariance;
import patch.apache.commons.math.linear.RealMatrix;
import resilienceManager.qmul.gemom.Gbroker;

import org.jfree.data.statistics.*; 

import inl.resilienceManager.qmul.gemom.TableSaver;

/*
 * COPYRIGHT DISCLAIMER
 * Synopsis: All the source codes presented in this document are intellectual
 * properties of Queen Mary, University of London.
 * 
 * @year 2010
 * @author Peng Jiang, John Bigham, Jiayi Wu Jinfu Wang------------QMUL
 * @version 1.0 
 */

public class CovMatrixData {

    private double[][]covMatrix;//this is the covariance matrix
    private RealMatrix rMatrix;
    double[][]meanAndStdDev;
    double [][]seriesData;
    
    public CovMatrixData(double [][]seriesData){
        
        this.seriesData = seriesData;
        
        Covariance cov = new Covariance(seriesData);
        rMatrix = cov.getCovarianceMatrix();
        covMatrix = rMatrix.getData();
    }
    
    public void printCovMatrix(){
        
         NumberFormat nf = NumberFormat.getInstance();
         nf.setMaximumFractionDigits(2);
         
         for(int i=0;i<covMatrix.length;i++)
         {for(int k=0;k<covMatrix.length;k++)
                 System.out.print(nf.format(covMatrix[i][k])+"  ");
         System.out.println();
         }
        
    }
    
    public double calculateVarsetItems(int... itemV){
        
        int[]items=itemV;
        Arrays.sort(items);
        double var=0;
        
        // var(x)+var(y)+var(z)+...
        for(int i=0;i<items.length;i++)
            var+=covMatrix[items[i]][items[i]];
        
        //2Cov(x,y) + 2Cov(x,z) +....
        for(int i=0;i<items.length;i++)
         {for(int k=i+1;k<items.length;k++)
            {var+= 2*covMatrix[items[i]][items[k]];}}
        //System.out.println(var);
        return var;
    }

   public void calculateMeanAndStdDev(){
    
        Number[][] seriesNumber = new Number[seriesData[0].length][seriesData.length];
         meanAndStdDev = new double[2][seriesData[0].length];
         
        for(int i=0;i<seriesData[0].length;i++)
            {for(int j=0;j<seriesData.length;j++)
                { seriesNumber[i][j]=seriesData[j][i];}
             meanAndStdDev[0][i]=Statistics.calculateMean(seriesNumber[i]);
             meanAndStdDev[1][i]=Statistics.getStdDev(seriesNumber[i]);
            }
     }
    
   public double[][] getMeanAndStdDev(){ return meanAndStdDev; } 
    
    public double[][] getCovMatrix(){return covMatrix;}
    
	public static double[][] getRandRates(int numS, int numNS){
//		inum is the number of samples, numNS num namespace
		
		double[][] rates= new double[numS][numNS];
		
		for(int i=0;i<numS; i++)
			for(int j=0; j<numNS; j++)
				rates[i][j]=0;
		
		for(int i=0; i<numS; i++)
			for(int j=0; j<numNS; j++)
		{
			if(rates[i][j]==0)
//				TODO this is important when cal the quantity of risk
				rates[i][j]=TableSaver.buildRand(10);

		}
		return rates;
	}
	
	public static double[][] sortRawMatrix(double[][] raw, String[] nss, HashMap<String,String> ns2id){
//		length of raw[i] and nss are equal to the total number of ns
		double[][] sorted = new double[raw.length][raw[0].length];
		for (int i=0; i<nss.length; i++){
			int id = Integer.parseInt(ns2id.get(nss[i]));
			for (int j=0; j<raw.length; j++){
				sorted[j][id-1]=raw[j][i];
			}
		}
		return sorted;
	}

	public static void main(String[] args){
		double[][] r = getRandRates(2,3);
		String[] s= new String[]{"a", "b", "c"};
		HashMap<String,String> ns2id = new HashMap<String, String>();
		ns2id.put("a", ""+3);
		ns2id.put("b", ""+1);
		ns2id.put("c", ""+2);
		
		double[][]sorted = sortRawMatrix(r, s, ns2id);
		
		HashMap<String,String> nsid = TableSaver.getMapNSID();
		System.out.println("sorted" + sorted);
//		doDB();
//		TableSaver.createNSTab(0);
//		TableSaver.createItemTab(0);
	}
	public static void doDB(){
//		TODO delecte old ini varTable
		double[][] rr = getRandRates(100,31);
		CovMatrixData vcovm = new CovMatrixData(rr);
		TableSaver.createMatrixTab(BuildDataTables.covertD2F(vcovm.getCovMatrix()));
		TableSaver.createMeanSdevTable();
		vcovm.calculateMeanAndStdDev();
//	XXX	TableSaver.Saving(BuildDataTables.covdertD2F(vcovm.getCovMatrix()));
		TableSaver.saveMatrix(BuildDataTables.covertD2F(vcovm.getCovMatrix()));
		TableSaver.saveMeanSDev(BuildDataTables.covertD2F(vcovm.getMeanAndStdDev()));
		
//		float[][] vcovMatrix=(TableSaver.loadMatrix());
		
//	TODO	TableSaver.saveBrokers(bs);
		
	}
	public static void doDB(Gbroker[] bs, double[][] rr, String[] nss){
//		TODO delecte old ini varTable
		//double[][] rr = getRandRates(100,31);
		HashMap<String,String> nsid = TableSaver.getMapNSID();
		double[][]sorted = sortRawMatrix(rr, nss, nsid);
		
		
		CovMatrixData vcovm = new CovMatrixData(sorted);
		TableSaver.createMatrixTab(BuildDataTables.covertD2F(vcovm.getCovMatrix()));
		TableSaver.createMeanSdevTable();
		vcovm.calculateMeanAndStdDev();
//	XXX	TableSaver.Saving(BuildDataTables.covdertD2F(vcovm.getCovMatrix()));
//		quantitive problem
//		TableSaver.saveMatrix(TableSaver.getRandTable());
		TableSaver.saveMatrix(BuildDataTables.covertD2F(vcovm.getCovMatrix()));
		TableSaver.saveMeanSDev(BuildDataTables.covertD2F(vcovm.getMeanAndStdDev()));
//		TableSaver.createBrokersTab();
//		TableSaver.saveBrokers(bs);
//		float[][] vcovMatrix=(TableSaver.loadMatrix());
		
//	TODO	TableSaver.saveBrokers(bs);
		
	}
}
